package com.zwcl.glass.goods.service;

import com.zwcl.common.core.domain.entity.ApiResult;
import com.zwcl.common.core.exception.BusinessException;
import com.zwcl.glass.goods.entity.GoodsSpu;
import com.zwcl.glass.goods.enums.FrameTagsScoreEnum;
import com.zwcl.glass.goods.enums.GlassTagsScoreEnum;
import com.zwcl.glass.tools.api.dto.UserTagsDto;
import com.zwcl.glass.tools.api.entity.UserReport;
import com.zwcl.glass.tools.api.enums.TestCodeEnum;
import com.zwcl.glass.tools.api.feign.ConclusionTagMapClient;
import com.zwcl.glass.tools.api.feign.UserReportFacadeClient;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 抽象类不支持@Service  @Component
 */
@Slf4j
public abstract class GoodsRecommend {
    @Autowired
    private UserReportFacadeClient userReportFacadeClient;

    @Autowired
    private GoodsSpuService goodsSpuService;

    public abstract List<GoodsSpu> getSpusByUserTag(String userTags,List<String> selectTags);

    public abstract Integer computeSpuScore(String spuTags, Map<String,String> userTags);

    public UserReport getUserReportTags(Integer userId,String paperCode){
        UserTagsDto userTagsDto=new UserTagsDto();
        //现在只查镜片
        userTagsDto.setPaperCodes(Arrays.asList(paperCode));
        userTagsDto.setUserId(userId);
        ApiResult<UserReport> userReportResult= userReportFacadeClient.getUserReportTags(userTagsDto);
        log.info("用户画像：{}",userReportResult.toString());
        if(userReportResult.getCode()!=200){
            log.error("调用glass-tools服务的getUserReportTags接口失败，原因：{}",userReportResult.getMessage());
            throw new BusinessException("调用glass-tools服务的getUserReportTags接口失败");
        }
        UserReport userReport = userReportResult.getData();
        return userReport;
    }

    /**
     * 在商品的基础上再次缩小范围，再做打分排序
     * @param spuList
     * @param tags
     * @return
     */
    public List<GoodsSpu> matchTags(List<GoodsSpu> spuList,List<String> tags,String paperCode){
        if(null==tags || tags.size()==0)
            return spuList;

        Map<String,String> conclusionAndTagMap = goodsSpuService.getConclusionAndTagMap(paperCode);
        //同类型中是或的关系，同类型之间是且的关系
        List<String> tagList = conclusionAndTagMap.entrySet().stream().filter(x->tags.contains(x.getKey())).map(x->x.getValue()).collect(Collectors.toList());
        log.info("用户选择的结论对应的标签：{}",tagList);
        Map<String,List<String>> tagMap=new HashMap<>();
        //加工处理选择的标签
        tagList.forEach(tagType->{
            String[] tagTypeArr=tagType.split(":");
            if(tagMap.containsKey(tagTypeArr[0])){
                List<String> typeTags= new ArrayList<>();
                typeTags.addAll(tagMap.get(tagTypeArr[0]));
                typeTags.addAll(Arrays.asList(tagTypeArr[1].split(",")));
                tagMap.put(tagTypeArr[0],typeTags);
            }else {
                tagMap.put(tagTypeArr[0],Arrays.asList(tagTypeArr[1].split(",")));
            }
        });
        if(tagMap.size()>0){
            Iterator<GoodsSpu> it = spuList.iterator();
            while(it.hasNext()){
                GoodsSpu item = it.next();
                //看是否满足用户的条件
                if (!matchUserSelect(item.getTags(), tagMap)) {
                    it.remove();
                }
            }
        }else {
            return null;
        }
        return spuList;
    }


    public Boolean matchUserSelect(String spuTags, Map<String,List<String>> userSelectTagMap){

        String[] spuTagsArr= spuTags.split("\\|");
        Set<String> spuTagsSet=new HashSet<>();
        for(int j=0;j<spuTagsArr.length;j++){
            if(StringUtils.isNotBlank(spuTagsArr[j])){
                spuTagsSet.add(spuTagsArr[j].trim());
            }
        }
        Boolean matchFlag = false;
        for(Map.Entry<String,List<String>> userSelectTag : userSelectTagMap.entrySet()){
            //折射率已经事先过滤了
            if(!userSelectTag.getKey().equals(GlassTagsScoreEnum.REFRACTION.getValue()) || !userSelectTag.getKey().equals(FrameTagsScoreEnum.RENDER.getValue())){
                List<String> userSelectTagList=userSelectTag.getValue();
                //Boolean temgMatchFlag=false;
                for(int i=0;i<userSelectTagList.size();i++){
                    if(spuTagsSet.contains(userSelectTagList.get(i))){
                        //temgMatchFlag=true;
                        matchFlag=true;
                        break;
                    }
                }
                //matchFlag=matchFlag & temgMatchFlag;
//                if(!matchFlag)
//                    break;
            }
        }
        return matchFlag;
    }
}
